/**
 * 
 */
package br.com.ema.maze.agents;

import java.awt.Color;
import java.util.ArrayList;
import java.util.List;

import br.com.ema.maze.character.strategy.MazeCharacterStrategy;
import br.com.ema.maze.components.MazeComponent;
import br.com.ema.maze.components.MazeSpace;
import br.com.ema.maze.listeners.MazeCharacterListener;

/**
 * @author Emanuel Cruz Rodrigues -> emanuelcruzrodrigues@gmail.com
 *
 */
public class MazeCharacter extends MazeComponent{
	
	private MazeSpace destination;
	private MazeSpace actualSpace;
	private MazeCharacterStrategy strategy;
	private List<MazeSpace> history;
	private List<MazeCharacterListener> characterListeners;
	private boolean running = false;
	private boolean alive = true;
	private Color color;
	private long sleepTime;
	
	private Thread thread;
	
	public MazeCharacter(long sleepTime) {
		history = new ArrayList<MazeSpace>();
		characterListeners = new ArrayList<MazeCharacterListener>();
		this.sleepTime = sleepTime;
	}
	
	public MazeSpace getActualSpace() {
		return actualSpace;
	}

	public void setActualSpace(MazeSpace actualSpace) {
		this.actualSpace = actualSpace;
		history.add(actualSpace);
		if (actualSpace != null && actualSpace.isExit()){
			callOnExitListeners(actualSpace);
			running = false;
		}
	}

	private void callOnExitListeners(MazeSpace actualSpace) {
		for (MazeCharacterListener listener : characterListeners) {
			listener.onExitMaze(this);
		}
	}
	
	public MazeSpace getDestination() {
		return destination;
	}
	public void setDestination(MazeSpace destination) {
		this.destination = destination;
	}
	
	public MazeCharacterStrategy getStrategy() {
		return strategy;
	}
	public void setStrategy(MazeCharacterStrategy strategy) {
		this.strategy = strategy;
	}
	
	public List<MazeSpace> getHistory() {
		return history;
	}
	
	public void addCharacterListener(MazeCharacterListener listener){
		characterListeners.add(listener);
	}

	public Color getColor() {
		return color;
	}
	public void setColor(Color color) {
		this.color = color;
	}

	public void animate(){
		running = true;
		if (thread == null){
			thread = new Thread(){
				public void run() {
					while (alive){
						try {
							if (running && strategy != null){
								strategy.executeStrategy(MazeCharacter.this);
								for (MazeCharacterListener listener : characterListeners) {
									listener.onMove(MazeCharacter.this);
								}
							}
							Thread.sleep(sleepTime);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
			};
			thread.start();
		}
	}

	public void stop() {
		running = false;
	}
	
	public void kill(){
		alive = false;
	}


}
